// Can I define a generic container?
// Using templates, not subclassing
// I'll try with template subtypes.
// Cool!  This works.  The only issues I have now are:
// 1. The "add" method should sometimes call push_back
//    (for a vector or a list), sometimes insert (for a set)
//    and sometimes insert(pair) for a hash.
// 2. The "partition" method needs to re-arrange the
//    container (for vector and list).
// 3. The "concatenate" or "add(Collection& other)" method needs
//    to re-arrange the container (for vector and list,
//    if both this and other.this point to same Container.
// 4. (FATAL): in main, I have to specify the template arguments
//    as part of the type, and I don't want to.


#include <list>
#include <iostream>
#include <fstream>

template<class Container, class Value>
class Collection {
private:
    Container items;

public:
    virtual ~Collection() {}

    // Iterator handling:
    typename Container::iterator begin();
    typename Container::iterator end();

    void add(Value x);
    void write(std::ostream& os);

};

template<class Container, class Value>
typename Container::iterator Collection<Container,Value>::begin() {
    return items.begin();
}

template<class Container, class Value>
typename Container::iterator Collection<Container,Value>::end() {
    return items.end();
}

template<class Container, class Value>
void Collection<Container,Value>::write(std::ostream& os) {
    for (typename Container::iterator iter = begin(); iter != end(); ++iter)
        os << ":" << *iter << " ";
    os << "\n";
}

template<class Container, class Value>
void Collection<Container,Value>::add(Value x) {
    items.push_back(x);
}

int main() {
    Collection<std::list<int>, int> *col = new Collection<std::list<int>, int>();

    col->add(1);
    col->add(2);
    col->add(3);

    col->write(std::cout);
}

